#pragma once
#include "base/function.h"
#include "base/logstream.h"

#include <stdio.h>
#include <string>

#define NT_LOG_TRACE net_tools::Log::logstream_->Init(__FILE__, __LINE__, net_tools::base::Logstream::TRACE)
#define NT_LOG_DEBUG net_tools::Log::logstream_->Init(__FILE__, __LINE__, net_tools::base::Logstream::DEBUG)
#define NT_LOG_INFO net_tools::Log::logstream_->Init(__FILE__, __LINE__, net_tools::base::Logstream::INFO)
#define NT_LOG_WARN net_tools::Log::logstream_->Init(__FILE__, __LINE__, net_tools::base::Logstream::WARN)
#define NT_LOG_ERROR net_tools::Log::logstream_->Init(__FILE__, __LINE__, net_tools::base::Logstream::ERROR)
#define NT_LOG_FATAL net_tools::Log::logstream_->Init(__FILE__, __LINE__, net_tools::base::Logstream::FATAL)
#define NT_LOG_ENDL (net_tools::base::Logendl *)(0)

namespace net_tools
{
  class Eventloop;
  namespace base
  {
    class Logstream;
    class Logbuffer;
    class Logfile;
  } // namespace base
  class Log
  {
    friend class base::Logstream;

  public:
    using outputfunc = std::function<void(void *, short int)>;
    Log(std::string app_name = _C::APP_NAME);
    ~Log();
    void Init(net_tools::Eventloop *eventloop, FILE *file_stream);
    static base::Logstream *Init();
    static void Set_level(base::Logstream::Log_level);
    static void Setstream(FILE *stream);
    static void Use_file_flush_file();
    static void Flush();
    static void Output(void *address, short int len);

    // static Logbuffer* logbuffer_;
    static void Defaultflush();
    static void Defaultoutput(void *address, short int len);
    static __thread base::Logstream *logstream_;
    static func flush_;
    static base::Logstream::Log_level level_;
    static base::Logfile *logfile_;
    static outputfunc output_;

  private:
    std::string app_name_;
  };

  class Logendl
  {
  public:
  private:
  };

} // namespace net_tools